package net.butfly.albacore.helper.async;

import java.util.Map;

import net.butfly.albacore.exception.SystemException;

import org.apache.commons.beanutils.BeanMap;
import org.springframework.scheduling.SchedulingTaskExecutor;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import org.springframework.scheduling.concurrent.ExecutorConfigurationSupport;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

public final class TaskExecutorFactory {
	public enum ExecutorMode {
		CONCURRENT(ConcurrentTaskExecutor.class), THREAD_POOL(ThreadPoolTaskExecutor.class);

		private Class<? extends SchedulingTaskExecutor> clazz;

		private ExecutorMode(Class<? extends SchedulingTaskExecutor> clazz) {
			this.clazz = clazz;
		}

		public SchedulingTaskExecutor getExecutor(Map<String, Object> params) {
			try {
				SchedulingTaskExecutor ex = this.clazz.newInstance();
				BeanMap bm = new BeanMap(ex);
				bm.putAll(params);
				if (ex instanceof ExecutorConfigurationSupport)
					((ExecutorConfigurationSupport) ex).initialize();
				return ex;
			} catch (Exception e) {
				throw new SystemException("ALC_000", "Unable to create instance of task executor of class: " + this.clazz.getName());
			}
		}
	};

	private TaskExecutorFactory() {
	};

	public static SchedulingTaskExecutor getExecutor(ExecutorMode mode, Map<String, Object> params) {
		return null == mode ? null : mode.getExecutor(params);
	}
}
